<template>
  <v-card class="system-permission-container">
    <v-toolbar flat>
      <v-toolbar-title>权限列表</v-toolbar-title>
      <v-divider class="mx-4" inset vertical />
      <v-spacer />
    </v-toolbar>
    <v-progress-linear
      indeterminate
      :active="optionLoading"
    />
    <v-expand-transition>
      <v-treeview
        v-if="showTreeView"
        :key="treeViewKey"
        :items="routes"
        item-text="meta.title"
        activatable
        open-all
        hoverable
        transition
      >
        <template v-slot:prepend="{ item }">
          <v-icon v-if="item.meta.icon" v-text="'mdi-'+item.meta.icon" />
        </template>
        <template v-slot:append="{ item }">
          <span v-if="item.component !== 'Layout'" class="d-none d-sm-inline">
            <v-chip v-for="role in item.roles" :key="role" outlined color="warning" class="mr-2" v-text="handleUserRolesMap(role)" />
            <v-chip v-for="group in item.group" :key="group" outlined color="primary" class="mr-2" v-text="handleUserGroupMap(group)" />
          </span>
          <v-btn icon :disabled="item.component === 'Layout'" @click="openDialog(item)">
            <v-icon dark>
              mdi-lock-reset
            </v-icon>
          </v-btn>
        </template>
      </v-treeview>
    </v-expand-transition>
    <v-dialog
      v-model="dialog"
      max-width="500px"
    >
      <v-card>
        <v-card-title>
          <span class="text-h5">权限设置</span>
        </v-card-title>
        <v-card-text>
          <p class="pt-3 font-weight-medium text-subtitle-1">角色</p>
          <v-checkbox
            v-for="role in userRolesData"
            :key="role.user_role_id"
            v-model="editPermissionForm.selectedRoles"
            :label="role.user_role_title"
            :value="role.user_role_id"
          />
          <v-divider />
          <p class="pt-3 font-weight-medium text-subtitle-1">用户组</p>
          <v-checkbox
            v-for="group in userGroupData"
            :key="group.user_group_id"
            v-model="editPermissionForm.selectedGroup"
            :label="group.user_group_title"
            :value="group.user_group_id"
          />
        </v-card-text>
        <v-card-actions>
          <v-spacer />
          <v-btn color="blue darken-1" text @click="close">取消</v-btn>
          <v-btn color="blue darken-1" text :loading="saveLoading" @click="save">保存</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </v-card>
</template>

<script>
import asyncRouteMap from '@/router/async_router'
import { getOptions, setOptions } from '@/api/options'
import { deepClone } from '@/utils/index'
export default {
  name: 'SystemPermission',
  data() {
    return {
      treeViewKey: new Date().getTime(),
      showTreeView: false,
      routes: [],
      optionLoading: false,
      userGroupData: [],
      userRolesData: [],
      permissionData: [],
      dialog: false,
      saveLoading: false,
      editPermissionForm: {
        component: '',
        selectedRoles: [],
        selectedGroup: []
      },
      defaultPermissionItem: {
        component: '',
        selectedRoles: [],
        selectedGroup: []
      }
    }
  },
  created() {
    this.initialize()
  },
  methods: {
    initialize() {
      this.optionLoading = true
      getOptions().then(response => {
        this.userGroupData = response.data.user_group || []
        this.userRolesData = response.data.user_roles || []
        this.permissionData = response.data.permission || []
        const asyncRouteData = asyncRouteMap.filter(item => !item.hidden)
        const asyncRoute = deepClone(asyncRouteData)
        this.routes = this.filterRoute(asyncRoute)
        this.showTreeView = true
      }).catch(error => {
        this.$message.error(error)
      }).finally(() => {
        this.optionLoading = false
      })
    },
    filterRoute(asyncRoute) {
      return asyncRoute.map(({ meta, component, children }) => {
        const route = { meta, component }
        if (this.permissionData[component]) {
          route.roles = this.permissionData[component].roles
          route.group = this.permissionData[component].group
        } else {
          route.roles = []
          route.group = []
        }
        if (children instanceof Array && children.length > 0) {
          route.children = this.filterRoute(children)
        }
        if (children === undefined && meta.btn && meta.btn instanceof Array) {
          route.children = this.filterRoute(meta.btn)
        }
        if (component === 'Layout') {
          route.meta.icon = 'view-compact-outline'
        } else if (component.indexOf(':') > -1) {
          route.meta.icon = 'gesture-tap-button'
        } else {
          route.meta.icon = 'format-page-break'
        }
        route.id = Math.random().toString(36).slice(-8)
        return route
      })
    },
    handleUserGroupMap(groupId) {
      if (groupId) {
        let groupTitle = ''
        this.userGroupData.forEach(item => {
          if (item.user_group_id === groupId) {
            groupTitle = item.user_group_title
          }
        })
        return groupTitle
      } else {
        return this.userGroupData.map(item => {
          const group = []
          group[item.user_group_id] = item.user_group_title
          return group
        })
      }
    },
    handleUserRolesMap(roleId) {
      if (roleId) {
        let roleTitle = ''
        this.userRolesData.forEach(item => {
          if (item.user_role_id === roleId) {
            roleTitle = item.user_role_title
          }
        })
        return roleTitle
      } else {
        return this.userRolesData.map(item => {
          const role = []
          role[item.user_role_id] = item.user_role_title
          return role
        })
      }
    },
    openDialog(item) {
      this.editPermissionForm.component = item.component
      this.editPermissionForm.selectedRoles = item.roles
      this.editPermissionForm.selectedGroup = item.group
      this.dialog = true
    },
    close() {
      this.editPermissionForm = this.defaultPermissionItem
      this.dialog = false
    },
    save() {
      this.saveLoading = true
      if (this.permissionData[this.editPermissionForm.component]) {
        this.permissionData[this.editPermissionForm.component].roles = this.editPermissionForm.selectedRoles
        this.permissionData[this.editPermissionForm.component].group = this.editPermissionForm.selectedGroup
      } else {
        this.$set(this.permissionData, this.editPermissionForm.component, { roles: this.editPermissionForm.selectedRoles, group: this.editPermissionForm.selectedGroup })
      }
      setOptions({ permission: this.permissionData }).then(() => {
        this.routes = this.filterRoute(this.routes)
        this.treeViewKey = new Date().getTime()
      }).catch(error => {
        this.$message.error(error)
      }).finally(() => {
        this.saveLoading = false
        this.close()
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.v-input--selection-controls {
  margin-top: 0;
  padding-top: 0;
  ::v-deep .v-messages {
    min-height: 0;
  }
}
</style>
